package com.ruoyi.web.controller.commonscontroller;

import com.ruoyi.web.entity.commons.ServerFile;
import com.ruoyi.web.mapper.commons.ServerFileMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@CrossOrigin
@RestController
@RequestMapping("/commons")
public class CommonsController {
    @Value("${file.upload-file}")
    private String uploadFile; //配置文件 服务器地址
    @Value("${file.upload-picture}")
    private String uploadPicture; //图片上传

    @Autowired
    private ServerFileMapper serverFileMapper;


    /**
     *  文件上传接口
     * @param file
     * @param request
     * @throws IOException
     * @throws java.io.IOException
     */
    @PostMapping("/file/upload")
    public ResponseEntity<Map<String, Object>> handleFileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException, java.io.IOException {
        if (file.isEmpty()) {
            return createErrorResponse(400, "文件为空");
        }

        // 获取文件名
        String originalFile = file.getOriginalFilename();

        // 获取当前日期，用于创建文件夹
        LocalDate currentDate = LocalDate.now();
        String dateFolder = currentDate.toString(); // 格式化为 yyyy-MM-dd

        // 构建文件的目标路径，例如: uploads/2024-12-13/文件名
        String targetFolder = uploadFile + "/" + dateFolder;
        File dateDirectory = new File(targetFolder);

        // 如果文件夹不存在，则创建
        if (!dateDirectory.exists()) {
            dateDirectory.mkdirs();
        }

        // 创建目标文件的路径
        String uuid = UUID.randomUUID().toString();
        String newFileName = uuid + originalFile.substring(originalFile.lastIndexOf("."));
        File targetFile = new File(dateDirectory, newFileName);
        // 获取文件扩展名
        String fileExtension = newFileName.substring(newFileName.lastIndexOf(".") + 1).toLowerCase();
        // 将文件存储到本地磁盘
        file.transferTo(targetFile);

        // 将文件信息保存到数据库（假设有一个ServerFile实体和serverFileMapper用于持久化文件记录）
        ServerFile serverFile = new ServerFile();
        serverFile.setFileUid(uuid);
        serverFile.setRealName(originalFile);
        serverFile.setServerName(newFileName);
        serverFile.setFilePath(targetFile.getPath()); // 设置文件路径
        serverFileMapper.addServerFile(serverFile);

        // 构建返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("url", uuid); // 返回文件 UID（服务器生成的）
        data.put("fileName", originalFile); // 返回文件的原始名称
        data.put("serverName", newFileName); // 返回服务器保存的文件名
        data.put("fileType", fileExtension); // 返回服务器保存的文件类型

        return createSuccessResponse(data, "文件上传成功");
    }

    /**
     * 文件下载
     * @param
     */
    @GetMapping("/file/download")
    public void downloadOrderFile(@RequestParam("fileId") String fileId, HttpServletResponse response) {
        // 获取文件信息
        ServerFile serverFile = serverFileMapper.getServerFileByUid(fileId);

        if (serverFile == null || serverFile.getFilePath() == null) { // 检查是否获取到有效的文件信息
            throw new RuntimeException("文件不存在");
        }

        String filePath = serverFile.getFilePath(); // 使用正确的属性名来获取文件路径
        File file = new File(filePath);

        if (!file.exists() || !file.isFile()) { // 确保文件存在且是常规文件
            throw new RuntimeException("非常规文件");
        }

        try {
            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setContentLengthLong(file.length());
            // 对文件名进行 URL 编码，并处理可能的浏览器兼容性问题
            String encodedFileName = URLEncoder.encode(serverFile.getRealName(), StandardCharsets.UTF_8.toString());
            encodedFileName = encodedFileName.replaceAll("\\+", "%20");

            // 设置 Content-Disposition 头部，包含编码后的文件名
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName);

            try (BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(file));
                 OutputStream outStream = response.getOutputStream()) {

                byte[] buffer = new byte[4096];
                int bytesRead;

                // 将文件内容写入响应的输出流
                while ((bytesRead = inStream.read(buffer)) != -1) {
                    outStream.write(buffer, 0, bytesRead);
                }
                outStream.flush();
            } catch (java.io.IOException e) {
                throw new RuntimeException(e);
            }
        } catch (IOException e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            e.printStackTrace();
        }
    }
//    @PostMapping("/xq/picture")
//    public ResponseEntity<Map<String, Object>> handleFileUpload(@RequestParam("file") List<MultipartFile> file, HttpServletRequest request) throws IOException, java.io.IOException {
//        if (file.isEmpty()) {
//            return createErrorResponse(400, "文件为空");
//        }
//
//        List<Map<String, Object>> fileDataList = new ArrayList<>();
//        for (MultipartFile files : file) {
//            // 获取文件名
//            String originalFile = files.getOriginalFilename();
//
//            if (originalFile == null || originalFile.isEmpty()) {
//                continue; // 如果文件名为空，跳过当前文件
//            }
//
//            // 创建目标文件
//            File targetFile = new File(uploadDir + "/" + originalFile);
//
//            // 检查目标目录是否存在，不存在则创建
//            if (!targetFile.getParentFile().exists()) {
//                targetFile.getParentFile().mkdirs();
//            }
//
//            // 设置文件新名
//            String uuid = UUID.randomUUID().toString();
//            String newFileName = uuid + originalFile.substring(originalFile.lastIndexOf("."));
//
//            // 将文件存储到本地磁盘中
//            files.transferTo(new File(uploadDir + "//" + newFileName));
//
//            // 保存到数据库
//            ServerFile serverFile = new ServerFile();
//            serverFile.setFileUid(uuid);
//            serverFile.setRealName(originalFile);
//            serverFile.setServerName(newFileName);
//            serverFile.setFileType(uploadDir + "//" + newFileName);
//            serverFileMapper.addServerFile(serverFile);
//
//            // 构建返回数据
//            Map<String, Object> fileData = new HashMap<>();
//            fileData.put("fileUid", uuid); // 返回文件 UID（服务器生成的）
//            fileData.put("realName", originalFile); // 返回文件的原始名称
//            fileData.put("serverName", newFileName); // 返回服务器保存的文件名
//            fileDataList.add(fileData);
//        }
//
//        if (fileDataList.isEmpty()) {
//            return createErrorResponse(400, "没有有效的文件上传");
//        }
//
//        // 返回多个文件的上传结果
//        Map<String, Object> data = new HashMap<>();
//        data.put("uploadedFiles", fileDataList); // 返回多个文件的 UID和其他信息
//        return createSuccessResponse(data, "文件上传成功");
//    }

    private ResponseEntity<Map<String, Object>> createSuccessResponse(Map<String, Object> body, String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", 200); // 添加状态码字段
        response.put("message", message);
        response.put("data", body); // 将原始body作为data字段的一部分
        return ResponseEntity.ok(response);
    }

    private ResponseEntity<Map<String, Object>> createErrorResponse(int status, String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("code", status); // 添加状态码字段
        response.put("message", message);
        response.put("status", status); // 保留原有的status字段，以防前端依赖此字段
        return ResponseEntity.status(status).body(response);
    }

    /**
     * 图片上传
     * @param file
     * @param request
     * @return
     */
    @PostMapping("/image/upload")
    public ResponseEntity<Map<String, Object>> handleFileUploadPicture(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) {
            return createErrorResponse(400, "文件为空");
        }

        // 获取域名和端口号
        String domain = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();

        try {
            // 清理文件名以避免潜在的安全问题
            String cleanedFileName = file.getOriginalFilename().replaceAll("[^\\u4E00-\\u9FA5a-zA-Z0-9-_\\.]", "_");

            int lastDotIndex = cleanedFileName.lastIndexOf('.');
            String fileExtension = "";
            if (lastDotIndex != -1) {
                fileExtension = cleanedFileName.substring(lastDotIndex);
            }

            // 生成UUID
            String uuid = UUID.randomUUID().toString();
            // 拼接UUID和文件后缀作为最终文件名
            String finalFileName = uuid + fileExtension;

            // 确保上传目录存在
            Path uploadPath = Paths.get(uploadPicture);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            Path filePath = uploadPath.resolve(finalFileName);

            // 尝试保存文件到指定路径
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
            } catch (java.io.IOException e) {
                return createErrorResponse(500, "无法存储文件: " + e.getMessage());
            }

            // 生成访问URL
            String fileDownloadUri = domain + "/file/document/" + URLEncoder.encode(finalFileName, "UTF-8");

            Map<String, Object> data = new HashMap<>();
            data.put("url", fileDownloadUri);
            data.put("fileName", finalFileName);
            return createSuccessResponse(data, "文件上传成功");

        } catch (java.io.IOException e) {
            e.printStackTrace();
            return createErrorResponse(500, "无法存储文件. 错误: " + e.getMessage());
        }
    }
}
